package wangjg.mda.gen.template;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;

import org.apache.commons.collections.MapUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;

public class VelocityImpl implements TemplateEngine {
	private String templCharset = "utf-8";
	private String genCharset = "utf-8";
	private String templateRoot;
	
	public void process(Map<String,Object> rootMap, File template, File out){
		OutputStream os = null;
		try{
			os = new FileOutputStream(out);
			Writer writer = new OutputStreamWriter(os, genCharset);
			this.process(rootMap, template, writer);
			writer.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			try{
				if(os!=null)os.close();
			}catch(Exception e){
				e.printStackTrace();
			}
		}
	}
	
	public void process(Map<String,Object> rootMap, File templateFile, Writer writer) {
		Template template = getTemplate(templateFile);
		VelocityContext context = new VelocityContext();
		for(Entry<String,Object> entry : rootMap.entrySet()){
			context.put(entry.getKey(), entry.getValue());
		}
		template.merge(context, writer);
	}
	
	public String evaluate(Map<String,Object> rootMap, String template){
        StringWriter writer = new StringWriter();
        writer = new StringWriter();
        this.evaluate(rootMap, template, writer);
        return writer.toString();
	}
	
	public void evaluate(Map<String,Object> rootMap, String template, Writer writer){
        Velocity.init();
		VelocityContext context = new VelocityContext();
		for(Entry<String,Object> entry : rootMap.entrySet()){
			context.put(entry.getKey(), entry.getValue());
		}
        Velocity.evaluate(context, writer, "VelocityImpl.evaluate", template);
	}

	private Template getTemplate(File template){
		Properties prop = new Properties();
		prop.setProperty("input.encoding", templCharset);
		prop.setProperty("userdirective", "wangjg.mda.gen.template.ReplaceDirective,wangjg.mda.gen.template.TrimDirective");
		prop.setProperty(VelocityEngine.FILE_RESOURCE_LOADER_PATH, getRootPath(template));
		VelocityEngine ve = new VelocityEngine();
		ve.init(prop);
		Template t = ve.getTemplate(getTemplateName(template));
		return t;
	}
	
	private String getTemplateName(File file){
		if(this.templateRoot==null){
			return file.getName();
		}else{
			int pos = this.templateRoot.length();
			String name = file.getPath();
			name = name.substring(pos);
			return name;
		}
	}
	
	private String getRootPath(File template){
		if(this.templateRoot!=null){
			return this.templateRoot;
		}else{
			return template.getParent();
		}
	}
	
	public String getTemplateRoot() {
		return templateRoot;
	}

	public void setTemplateRoot(String templateRoot) {
		this.templateRoot = templateRoot;
	}

	public static void main(String args[]) {
		VelocityImpl v = new VelocityImpl();
		v.evaluate(MapUtils.EMPTY_MAP, "$mod");
		v.evaluate(MapUtils.EMPTY_MAP, "$mod");
	}
}
